﻿/*************************************************************************************

- CLR版本：        4.0.30319.42000
- 类 名 称：       起保停
- 机器名称：       YTE
- 命名空间：       LD.BC
- 文 件 名：       起保停
- 创建时间：       2022/7/1 11:41:56
- 作    者：       YTE
- 说   明：
- 修改时间：
- 修 改 人：
  *************************************************************************************/

using LD.Host;
using log4net.Core;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace LD.BC
{
    public class 起保停
    {
        private TaskEx TaskEx = new TaskEx();
        private bool stopTrig = false;
        private bool resetTrig = false;
        private bool pauseTrig = false;
        public void Start()
        {
            TaskEx.Start(Monitor, null);
        }
        public void Closed()
        {
            TaskEx?.Cancel();
        }
        private void Monitor(object obj)
        {
            try
            {
                var DI = BcFactory.Instance.Config.IoList.Where(p => p.IoType == (int)IoType.输入).ToList();
                var DO = BcFactory.Instance.Config.IoList.Where(p => p.IoType == (int)IoType.输出).ToList();

                Jerk(DI, DO);
                //Raster(DI, DO);
                Reset(DI, DO);
                Door();
                Alm();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }

        private void Alm()
        {
            var almIo = BcFactory.Instance.Config.IoList
                        .Where(p => p.IoType == (int)IoType.输入 &&
                                    p.FixType == RunEnum.报警.ToString())
                        .ToList();
            foreach (var item in almIo)
            {
                if ((int)item.ValidateLevel == BcFactory.Instance.Control.GetIn(item.No))
                {
                    //通知全局
                    BcFactory.Instance.RunState(RunEnum.急停);
                    BCAlertHelper.Log($"{item.Name}报警", LogLevel.严重);
                }
            }
        }

        private void Door()
        {
            var _door = from q in BcFactory.Instance.Config.IoList
                        join x in BcFactory.Instance.Config.IoList on q.No equals x.No
                        where q.IoType == 0 && q.FixType == RunEnum.安全门.ToString() && x.IoType == 0
                        select new { q, x.Name };
            foreach (var item in _door)
            {
                var on_off = BcFactory.Instance.Control.GetIn(item.q.No);

                if (on_off == 1 && (bool)Cache.GetCache(item.Name))
                {
                    //报警
                    BCAlertHelper.Log(item.Name + "打开", LogLevel.严重);
                }
            }
        }
        /// <summary>
        /// 急停
        /// </summary>
        /// <param name="DI"></param>
        /// <param name="DO"></param>
        private void Jerk(List<TB_IO> DI, List<TB_IO> DO)
        {
            var jiting = DI.Where(p => p.FixType == RunEnum.急停.ToString()).FirstOrDefault();
            if (jiting != null)
            {
                //检测信号
                var on_off = BcFactory.Instance.Control.GetIn((ushort)jiting.No);
                if (on_off == 1)
                {
                    //所有轴停止
                    BcFactory.Instance.Control.StopALL();

                    //灯全部关闭
                    //ClosedLight();

                    BCAlertHelper.Log("急停", LogLevel.严重);

                    //红灯
                    //Light(LightEnum.红灯, LevelType.低电平);

                    //蜂鸣
                    //SoundHelper.Instance.Signal(LevelType.低电平);

                    //通知全局
                    //Appbus.StateEnum = StateEnum.手动模式;

                }
            }
        }
        /// <summary>
        /// 复位
        /// </summary>
        /// <param name="DI"></param>
        /// <param name="DO"></param>
        private void Reset(List<TB_IO> DI, List<TB_IO> DO)
        {
            if (stopTrig)
                return;
            if (pauseTrig)
                return;
            if (Appbus.StateEnum == StateEnum.自动模式)
                return;
            //复位
            var reset = DI.Where(p => p.FixType == RunEnum.复位.ToString()).FirstOrDefault();
            if (reset != null)
            {
                //检测信号
                var on_off = BcFactory.Instance.Control.GetIn((ushort)reset.No);
                resetTrig = Convert.ToBoolean(on_off);
                if (on_off == 0 &&
                    Appbus.StateEnum == StateEnum.手动模式)
                {
                    Reset();
                }
            }
        }
     
        /// <summary>
        /// 关闭所有灯
        /// </summary>
        public void ClosedLight()
        {
            Light(LightEnum.红灯, LevelType.高电平);
            Light(LightEnum.黄灯, LevelType.高电平);
            Light(LightEnum.绿灯, LevelType.高电平);
        }
        public void Light(LightEnum lightType, LevelType signal)
        {
            var light = BcFactory.Instance.Config?.IoList.Where(p => p.IoType == (int)IoType.输出 && p.FixType == lightType.ToString()).FirstOrDefault();
            if (light != null)
                BcFactory.Instance.Control.SetOut((ushort)light.No, (ushort)signal);

            Task.Delay(5).Wait();
        }
        public void Sound(LevelType signal)
        {
            if (signal == LevelType.低电平)
            {
                if (!(bool)Cache.GetCache(CONST.BC_SOUND))
                    return;
            }
            var sound = BcFactory.Instance.Config.IoList
                        .Where(p => p.IoType == (int)IoType.输出 && p.FixType == LightEnum.蜂鸣.ToString())
                        .FirstOrDefault();
            if (sound != null)
                BcFactory.Instance.Control.SetOut((ushort)sound.No, (ushort)signal);
            Task.Delay(5).Wait();
        }
        public void Reset()
        {
            if (BCAlertHelper.GetErrorQty)
                return;

            if (BcFactory.Instance.Control.IsMoving())
                return;

            if ((bool)Cache.GetCache(CONST.BC_ISRESETING))
                return;

            /*
             * 复位加入到线程中运行
             * 不加可能阻塞线程，导致下面的逻辑无法报警
             * */
            Task.Run(() =>
            {
                Log4.Info("开始复位");
                Cache.SetCache(CONST.BC_ISRESETING, true);
                //灯全部关闭
                ClosedLight();

                //复位灯亮
                Light(LightEnum.复位灯, LevelType.低电平);

                //黄灯
                Light(LightEnum.黄灯, LevelType.低电平);

                //运动
                foreach (var item in BcFactory.Instance.Config.AxisParam.OrderByDescending(y => y.AxisId))
                {
                    BcFactory.Instance.Control.Move_BackZero(item.AxisId);
                }

                //灯全部关闭
                ClosedLight();

                //绿灯
                Light(LightEnum.绿灯, LevelType.低电平);

                //复位灯关闭
                Light(LightEnum.复位灯, LevelType.高电平);
                Cache.SetCache(CONST.BC_ISRESETING, false);

                //通知全局
                BcFactory.Instance.RunState(RunEnum.复位);

                Log4.Info("复位完成");
                Cache.SetCache(CONST.BC_ISRESET, true);
            });
        }
    }
}
